package com.sky.chapter3.lock;


import java.util.concurrent.locks.ReentrantLock;
/**
 * @author : wushikai
 * <p>
 * date : 2022-07-04
 * synchronized的局限性
 *
 * synchronized是java内置的关键字，它提供了一种独占的加锁方式。synchronized的获取和释放锁由jvm实现，
 * 用户不需要显示的释放锁，非常方便，然而synchronized也有一定的局限性，例如：
 *     当线程尝试获取锁的时候，如果获取不到锁会一直阻塞，这个阻塞的过程，用户无法控制
 *     如果获取锁的线程进入休眠或者阻塞，除非当前线程异常，否则其他线程尝试获取锁必须一直等待
 *
 * JDK1.5之后发布，加入了Doug Lea实现的java.util.concurrent包。
 * 包内提供了Lock类，用来提供更多扩展的加锁功能。Lock弥补了synchronized的局限，提供了更加细粒度的加锁功能
 */
public class LockDemo1 {
    private static int num = 0;
    private static ReentrantLock lock = new ReentrantLock();
    private static void safeAdd() {
        lock.lock();
        try {
            num++;
        } finally {
            lock.unlock();
        }
    }

    private static  void notSaveAdd(){

        num++;
    }

    private static class T extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 10000; i++) {
                LockDemo1.safeAdd();
//                LockDemo1.notSaveAdd();
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        T t1 = new T();
        T t2 = new T();
        T t3 = new T();
        t1.start();
        t2.start();
        t3.start();
        t1.join();
        t2.join();
        t3.join();
        System.out.println(LockDemo1.num);
    }
}
